package work.thread_eg.concurrent.atomic;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicStampedReference;
import java.util.concurrent.atomic.LongAdder;

/**
 * 使用原子类保证操作的原子性 底层是基于CAS的 类似自旋锁 （Unsafe类) CPU原语支持 不能中断
 *  Atomic本身方法都是原子性的 但是不能保证多个方法连续调用是原子性的
 *  使用Atomic相当于无锁 效率比较高
 *
 *  1) ABA问题
 *  AtomicStampedReference可以用来解决ABA问题
 *  基本数据类型的ABA问题不大 引用类型需要注意 会有数据错乱问题
 */
public class AtomicTest02 {
    AtomicInteger count = new AtomicInteger(0);
    int sum = 0;

    // LongAdder比AtomicInteger效率高
    // 在线程数多的时候 效率比较快 (分段式锁)
    // 把值放在一个数组里 把线程分块锁在数组的某个元素进行处理  最后再进行合并
    LongAdder longAdder = new LongAdder();

    synchronized void m() {
        // incrementAndGet方法是原子性的
        for(int i=0 ; i<10000; i++) {
            count.incrementAndGet();
            sum++;
        }
    }
    public static void main(String[] args) {
        AtomicTest02 t = new AtomicTest02();
        List<Thread> threads = new ArrayList<>();
        for(int i=0 ; i<10; i++) {
            threads.add(new Thread(t::m,"thread" + i));
        }
        threads.forEach(o->o.start());
        // 10个线程跑完之后
        threads.forEach(o->{
            try {
                o.join();
            }catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        System.out.println(t.count);
        System.out.println(t.sum);
    }
}
